package com.myzl.coal.utils;

import com.myzl.coal.dto.SendCmdDTO;
import com.myzl.common.enums.PlcFunctionEnum;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import static com.myzl.coal.utils.HexUtil.*;

/**
 * @author Administrator
 * @date 2022年10月26日10:19:06
 */
public class ModBusCommandUtil {

    /**
     * 读取单个寄存器
      * @param start 寄存器读取开始位
     * @param deviceId 读取的设备id
     */
    public static SendCmdDTO readOne(Integer deviceType, Integer deviceId, int start){
        return readMore(deviceType,deviceId,start,1);
    }

    /**
     * 读取多个寄存器
     * @param start 寄存器读取开始位
     * @param number 寄存器读取数量
     * @param deviceId 读取的设备id
     */
    public static SendCmdDTO readMore(Integer deviceType, Integer deviceId, int start, int number){
        byte[] message = PlcCommand.read(deviceId,start, number);
        return buildSendCmd(deviceType,deviceId,message);
    }

    /**
     * 写单个寄存器
     * @param start 寄存器写入开始位
     * @param data 写入的数据
     * @param deviceId 写入的设备id
     */
    public static SendCmdDTO writeRegistersOne(Integer deviceType, Integer deviceId, int start, Integer data){
        return writeRegistersMore(deviceType,deviceId,start, Collections.singletonList(data));
    }

    /**
     * 写单个寄存器
     * @param start 寄存器写入开始位
     * @param data 写入的数据
     * @param deviceId 写入的设备id
     */
    public static SendCmdDTO writeRegistersMore(Integer deviceType, Integer deviceId, int start, List<Integer> data){
        byte[] dataBytes = PlcCommand.getDataListBytes(data);
        byte[] message = PlcCommand.write(deviceId,PlcFunctionEnum.WRITE_HOLDING_REGISTERS.getCode(),start,data.size(),dataBytes);
        return buildSendCmd(deviceType,deviceId,message);
    }


    /**
     * 写单个线圈
     * @param start 线圈写入开始位
     * @param data 写入的数据
     * @param deviceId 写入的设备id
     */
    public static SendCmdDTO writeCoilsOne(Integer deviceType, Integer deviceId, int start, Integer data){
        return writeCoilsMore(deviceType,deviceId,start, Collections.singletonList(data));
    }

    /**
     * 写多个线圈
     * @param start 线圈写入开始位
     * @param data 写入的数据
     * @param deviceId 写入的设备id
     */
    public static SendCmdDTO writeCoilsMore(Integer deviceType, Integer deviceId, int start, List<Integer> data){
        byte[] dataBytes = PlcCommand.getDataListBytes(data);
        byte[] message = PlcCommand.writeCoils(deviceId,PlcFunctionEnum.WRITE_ONE_COILS.getCode(),start,dataBytes);
        return buildSendCmd(deviceType,deviceId,message);
    }

    private static SendCmdDTO buildSendCmd(Integer deviceType, Integer deviceId, byte[] message ){
        String messageStr = bytesToHexString(message);
        byte[] keyBytes = Arrays.copyOfRange(message, 0, 2);
        byte[] flagBytes = Arrays.copyOfRange(message, 8, 10);
        String key = bytesToHexString(keyBytes);
        String flag = bytesToHexString(flagBytes);
        SendCmdDTO sendCmdDTO = new SendCmdDTO();
        sendCmdDTO.setKey(key);
        sendCmdDTO.setAddress(flag);
        sendCmdDTO.setCallBack(true);
        sendCmdDTO.setDeviceId(deviceId);
        sendCmdDTO.setDeviceType(deviceType);
        sendCmdDTO.setSendType("hex");
        sendCmdDTO.setCommand(message);
        sendCmdDTO.setCommandStr(messageStr);
        return sendCmdDTO;
    }
}
